/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hk.ces.oxfam.patch.encryPayment;

import hk.ces.oxfam.patch.TransactionPatch;
import hk.ces.oxfam.patch.TransactionStrategy;
import hk.ces.oxfam.patch.TransactionStrategyType;
import hk.ces.oxfam.patch.db.SQLUtil;
import hk.ces.oxfam.patch.db.result.SQLResult;
import hk.ces.oxfam.patch.db.sql.PreparedSQL;
import hk.ces.oxfam.patch.sql.ExcuteUtil;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.binary.Base64;

/**
 *
 * @author daweihuang
 */
@TransactionStrategy(TransactionStrategyType.COMMIT_IN_ENGINE)
public class EncryPaymentInfo implements TransactionPatch
{

  private static final int BATCHCOUNT = 1000;
  private long recoreds = 0;
  private long endId = 0;
  private long startId = 0;

  public void run(Connection connection) throws SQLException
  {
    recoreds = this.findMaxSize(connection);
    System.out.println(recoreds + "size : ===========");
    endId = BATCHCOUNT;
    while (true)
    {
      if (endId < recoreds)
      {
        encry(connection, startId, endId);
        startId = endId;
        endId += BATCHCOUNT;
      }
      else
      {
        encry(connection, startId, recoreds);
        break;
      }
    }
  }
  public static int i = 0;

  private void encry(Connection connection, long startId, long endId) throws SQLException
  {
    StringBuffer sql = new StringBuffer(256);
    sql.append("select id, creditCardNo, creditCardAuthorizationCode, nameOnCard from paymentinfo where id > ").append(startId).append(" AND id <=").append(endId);
    sql.append(" and ((CREDITCARDNO is not null and CREDITCARDNO != '') ");
    sql.append(" or (CREDITCARDAUTHORIZATIONCODE is not null and CREDITCARDAUTHORIZATIONCODE != '') ");
    sql.append(" or (NAMEONCARD is not null and NAMEONCARD != '')) ");
    Object[] params = new Object[]
    {
    };
    SQLResult resultCount = SQLUtil.query(connection, new PreparedSQL(sql.toString(), params));
    List<PaymentInfoObject> list = new ArrayList();

    for (Object obj : resultCount.getRows())
    {

      Object[] columns = (Object[]) obj;
      PaymentInfoObject info = new PaymentInfoObject();

      info.setId((Long) columns[0]);

      info.setCreditCardNo(this.setEncrypt((String) columns[1]));

      info.setCreditCardAuthorizationCode(this.setEncrypt((String) columns[2]));
      info.setNameOnCard(this.setEncrypt((String) columns[3]));
      list.add(info);
    }
    
    String updateSql = "update paymentinfo set creditCardNo = ?, creditCardAuthorizationCode = ?, nameOnCard = ?  where id = ?";
    for (PaymentInfoObject pay : list)
    {
      System.out.println(pay.getCreditCardNo() + " " + pay.getCreditCardAuthorizationCode() + " " + pay.getNameOnCard() + " " + pay.getId());
      ExcuteUtil.excute(connection, new hk.ces.oxfam.patch.sql.PreparedSQL(updateSql, new Object[]
      {
        pay.getCreditCardNo(), pay.getCreditCardAuthorizationCode(), pay.getNameOnCard(), pay.getId()
      }));
    }
  }

  private Long findMaxSize(Connection connection) throws SQLException
  {
    String sql = "select max(id) from paymentinfo";
    SQLResult resultCount = SQLUtil.query(connection, new PreparedSQL(sql, new Object[]{}));
    Object[] objs = resultCount.getRows().get(0);
    return objs != null ? (Long) objs[0] : 0;
  }

  public String setEncrypt(String sources)
  {
    if (sources == null)
    {
      return " ";
    }
    return Base64.encodeBase64String(sources.getBytes());
  }

  public static String getDecrypt(String encrySource)
  {
    if (encrySource == null)
    {
      return " ";
    }

    StringBuffer decryptPath = new StringBuffer(128);
    for (byte b : Base64.decodeBase64(encrySource))
    {
      decryptPath.append(String.valueOf((char) b));
    }
    return decryptPath.toString();
  }
}
